﻿using Furion;
using Serilog;
using Serilog.Core;
using Serilog.Events;
using Serilog.Filters;
using Serilog.Sinks.MSSqlServer;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TulingMember.Core
{
    public class LogAudit
    {

        protected static Logger instance;
        protected static object locker = new object();
        public static Logger Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (locker)
                    {
                        if (instance == null) //防止线程重入
                        {
                            var columnOptions = new ColumnOptions();
                            columnOptions.Store.Remove(StandardColumn.MessageTemplate);
                            columnOptions.Store.Remove(StandardColumn.Properties);
                            columnOptions.Store.Remove(StandardColumn.Exception);
                            columnOptions.Store.Remove(StandardColumn.Level);
                            columnOptions.AdditionalColumns = new Collection<SqlColumn>
                             {
                                new SqlColumn { DataType = SqlDbType.NVarChar, DataLength = 50, ColumnName = "Table" },
                                new SqlColumn { DataType = SqlDbType.NVarChar, DataLength = 50, ColumnName = "Column" },
                                new SqlColumn { DataType = SqlDbType.NVarChar,  ColumnName = "NewValue" },
                                new SqlColumn { DataType = SqlDbType.NVarChar, ColumnName = "OldValue" },
                                new SqlColumn { DataType = SqlDbType.NVarChar, DataLength = 50, ColumnName = "Operate" },
                                new SqlColumn { DataType = SqlDbType.DateTime, DataLength = 4000, ColumnName = "CreatedTime" },
                                new SqlColumn { DataType = SqlDbType.BigInt, ColumnName = "CreatedUserId" },
                                new SqlColumn { DataType = SqlDbType.NVarChar, DataLength = 50, ColumnName = "CreatedUser" },
                                new SqlColumn { DataType = SqlDbType.BigInt, ColumnName = "BatchNo" }
                            };
                            instance = new LoggerConfiguration()  
                                .WriteTo.MSSqlServer(
                                    connectionString: App.Configuration["ConnectionStrings:SqlServerConnectionString"],
                                    sinkOptions: new MSSqlServerSinkOptions {
                                        TableName = "Audit", 
                                        AutoCreateSqlTable = true
                                    }, 
                                    restrictedToMinimumLevel: LogEventLevel.Debug,
                                    columnOptions: columnOptions).CreateLogger();
                        }
                    }
                }
                return instance;
            }
        }
        public static void Log( Audit audit) {
            Instance.ForContext("Table",audit.Table)
                .ForContext("Column", audit.Column)
                .ForContext("NewValue", audit.NewValue)
                .ForContext("OldValue", audit.OldValue)
                .ForContext("Operate", audit.Operate)
                .ForContext("CreatedTime", audit.CreatedTime)
                .ForContext("CreatedUserId", audit.CreatedUserId)
                .ForContext("CreatedUser", audit.CreatedUser)
                .ForContext("BatchNo", audit.BatchNo)
                .Information("");
        }
    }
}
